<?php

namespace App\Models\Game\Platform;

use App\Models\Game\Model;
use App\Models\Game\Platform\Org\AccessKey;
use App\Models\Game\Platform\Org\Config;
use App\Models\Game\Platform\Org\IP;
use App\Models\Traits\Game\LogsActivity;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\SoftDeletes;

class Org extends Model
{
    use SoftDeletes, LogsActivity;

    /**
     * 数据表名称
     *
     * @var string
     */
    protected $table = 't_plat_org';

    /**
     * 查询后隐藏的字段
     *
     * @var array
     */
    protected $hidden = [
        'deleted',
        'created',
        'updated',
    ];

    /**
     * 可以批量赋值的字段
     *
     * @var array
     */
    protected $fillable = [
        'parent_id',
        'path',
        'name',
        'code',
        'sort',
    ];

    /**
     * 全部平台填充code
     */
    const ALL_CODE = '**';

    /**
     * 获得IP白名单
     *
     * @return HasMany
     */
    public function ips(): HasMany
    {
        return $this->hasMany(IP::class, 'plat_code', 'code');
    }

    /**
     * 获得平台配置
     *
     * @return HasOne
     */
    public function config(): HasOne
    {
        return $this->hasOne(Config::class, 'plat_code', 'code');
    }

    /**
     * 获得访问密钥
     *
     * @return HasOne
     */
    public function accessKey(): HasOne
    {
        return $this->hasOne(AccessKey::class, 'plat_code', 'code');
    }

    /**
     * 平台关联子孙节点 (包括当前节点)
     *
     * @var Collection
     */
    protected $orgs;

    /**
     * 获取平台关联子孙节点 (包括当前节点)
     *
     * @return Collection
     */
    public function orgs(): Collection
    {
        if (is_null($this->orgs)) {
            // 查询子孙节点
            $this->orgs = $this->newQuery()
                ->where('path', 'like', $this->path . '.%')
                ->get();
            // 追加当前节点
            $this->orgs->push($this);
        }
        return $this->orgs;
    }

    /**
     * 查询所有正常数据
     *
     * @param int $id
     * @return \Illuminate\Database\Eloquent\Collection
     */
    protected function selectAll($id)
    {
        return $this->selectAllById($id);
    }

    /**
     * 查询所有正常数据
     *
     * @param int $id
     * @return \Illuminate\Database\Eloquent\Collection
     */
    protected function selectAllById($id)
    {
        if (null == ($org = $this->newQuery()->find($id))) {
            return $this->newCollection();
        }

        return $this->newQuery()->where(function ($query) use ($org) {
            $query->where('path', 'like', $org->path . '.%')->orWhere('id', '=', $org->id);
        })
            ->orderBy('parent_id', 'asc')
            ->orderBy('sort', 'asc')
            ->get();
    }

    /**
     * 查询所有子孙节点
     *
     * @param int $id
     * @return \Illuminate\Database\Eloquent\Collection
     */
    protected function selectChildById($id)
    {
        if (null == ($org = $this->newQuery()->find($id))) {
            return $this->newCollection();
        }

        return $this->newQuery()->where('path', 'like', $org->path . '.%')
            ->orderBy('parent_id', 'asc')
            ->orderBy('sort', 'asc')
            ->get();
    }

    /**
     * 查询多条数据【ID】
     *
     * @param array $ids
     * @return \Illuminate\Database\Eloquent\Collection
     */
    protected function selectByIds($ids)
    {
        return $this->newQuery()->whereIn('id', $ids)
            ->orderBy('parent_id', 'asc')
            ->orderBy('sort', 'asc')
            ->get();
    }

    /**
     * 制作授权平台数据
     *
     * @param array $ids
     * @return \Illuminate\Database\Eloquent\Collection
     */
    protected function makeAllOrgs($ids)
    {
        $orgs = $this->newCollection();

        // 循环获取所有平台节点
        collect($ids)->map(function ($id) {
            return Org::selectAllById($id)->all();
        })
            // 合并授权树
            ->each(function ($items, $key) use ($orgs) {
                $orgs->push(...$items);
            });

        return $orgs->unique('id')->sortBy('parent_id')->sortBy('sort');
    }
}
